﻿using System;
using System.Collections.Generic;

using System.Reflection;
using System.Text;
using System.Web;
using DotNETX.Web.Authority;

namespace DotNETX.Web.Module
{

    /// <summary>
    /// 用法：web.config 中添加配置节
    /// <add name="AuthorityModule" type="DotNETX.Web.Module.AuthorityModule, DotNETX.Web"/>
    /// 
    /// </summary>
    public class AuthorityModule : IHttpModule
    {
        public AuthorityModule()
        {
            Validaters = new List<IAuthorityValidater>();
            LoadValidaters();
            if (Config.Rediret2LoginUrl) InvalidRedirecter = new Invalid2LoginUrlRedirecter();
        }

        public void Dispose()
        {
        }

        public void Init(HttpApplication app)
        {
            app.PreRequestHandlerExecute += this.Context_PreRequestHandlerExecute;
        }

        void Context_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            HttpContext context = HttpContext.Current;

            AuthorityValidateResult result = new AuthorityValidateResult() { Level = 0, Passable = true, Message = "Default" };
            if (Validaters != null)
            {
                foreach (IAuthorityValidater av in Validaters)
                {
                    try
                    {
                        if (av != null)
                        {
                            AuthorityValidateResult avr = av.Validate(context);
                            if (avr.Level > result.Level) result = avr;
                            else if (avr.Level == result.Level && !avr.Passable) result = avr;
                            if (result.Level == int.MaxValue && !result.Passable) break;
                        }
                    }
                    catch (Exception ex)
                    {
                        continue;
                    }
                }
            }
            if (!result.Passable)//权限认证失败
            {
                if (InvalidRedirecter != null && InvalidRedirecter.Redirect != null)
                {
                    InvalidRedirecter.Redirect(context, result.Message);
                }
                else
                {
                    context.Response.Clear();
                    context.Response.Write(DotNETX.Utility.Text.HtmlUtils.CreateHtml("身份验证失败", result.Message));
                    context.Response.End();
                }
            }
            else//权限认证通过
            {
                if (ValidRedirecter != null && ValidRedirecter.Redirect != null)
                {
                    ValidRedirecter.Redirect(context, result.Message);
                }
            }
        }

        public List<IAuthorityValidater> Validaters { get; set; }

        public IRedirecter ValidRedirecter { get; set; }

        public IRedirecter InvalidRedirecter { get; set; }


        protected void LoadValidaters()
        {
            string folder = HttpContext.Current.Server.MapPath("~/bin");
            if (!System.IO.Directory.Exists(folder)) return;
            System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(folder);
            foreach (System.IO.FileInfo fi in dirInfo.GetFiles("*.dll"))
            {
                try
                {
                    Assembly assembly = Assembly.LoadFrom(fi.FullName);
                    foreach (Type t in assembly.GetTypes())
                    {
                        if (t.IsClass && t.IsPublic && !t.IsAbstract && t.GetInterface(typeof(IAuthorityValidater).FullName) == typeof(IAuthorityValidater))
                        {
                            try
                            {
                                object obj_validater = assembly.CreateInstance(t.FullName);
                                if (obj_validater is IAuthorityValidater) Validaters.Add(obj_validater as IAuthorityValidater);
                            }
                            catch
                            {

                            }
                        }
                    }
                }
                catch
                {

                }
            }

        }
    }
}
